package com.christina.engine.parameter.builder;

import com.christina.service.domain.travel.model.TravelPlanRequest;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;

/**
 * 出行规划请求建造者
 * 使用建造者模式构建TravelPlanRequest对象
 * 
 * @author Christina
 */
@Component
public class TravelPlanRequestBuilder extends ParameterBuilder<TravelPlanRequest> {
    
    private static final List<String> VALID_PRIORITIES = Arrays.asList(
            "SPEED", "COMFORT", "ECONOMY", "BALANCED");
    
    private static final List<String> VALID_TRANSPORT_MODES = Arrays.asList(
            "FLIGHT", "TRAIN", "BUS", "CAR", "ANY");
    
    /**
     * 创建新的建造者实例
     * 
     * @return 建造者实例
     */
    public static TravelPlanRequestBuilder newBuilder() {
        return new TravelPlanRequestBuilder();
    }
    
    /**
     * 设置用户ID
     * 
     * @param userId 用户ID
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder userId(Long userId) {
        return (TravelPlanRequestBuilder) addParameter("userId", userId);
    }
    
    /**
     * 设置出发地
     * 
     * @param origin 出发地
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder origin(String origin) {
        return (TravelPlanRequestBuilder) addParameter("origin", origin);
    }
    
    /**
     * 设置目的地
     * 
     * @param destination 目的地
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder destination(String destination) {
        return (TravelPlanRequestBuilder) addParameter("destination", destination);
    }
    
    /**
     * 设置出发时间
     * 
     * @param departureTime 出发时间
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder departureTime(LocalDateTime departureTime) {
        return (TravelPlanRequestBuilder) addParameter("departureTime", departureTime);
    }
    
    /**
     * 设置出发时间（字符串格式）
     * 
     * @param departureTimeStr 出发时间字符串
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder departureTime(String departureTimeStr) {
        return (TravelPlanRequestBuilder) addParameter("departureTimeStr", departureTimeStr);
    }
    
    /**
     * 设置乘客数量
     * 
     * @param passengerCount 乘客数量
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder passengerCount(Integer passengerCount) {
        return (TravelPlanRequestBuilder) addParameter("passengerCount", passengerCount);
    }
    
    /**
     * 设置预算限制
     * 
     * @param budgetLimit 预算限制
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder budgetLimit(Double budgetLimit) {
        return (TravelPlanRequestBuilder) addParameter("budgetLimit", budgetLimit);
    }
    
    /**
     * 设置预算
     * 
     * @param budget 预算
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder budget(Double budget) {
        return budgetLimit(budget);
    }
    
    /**
     * 设置交通方式
     * 
     * @param transportMode 交通方式
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder transportMode(String transportMode) {
        return (TravelPlanRequestBuilder) addParameter("transportMode", transportMode);
    }
    
    /**
     * 设置优先级
     * 
     * @param priority 优先级
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder priority(String priority) {
        return (TravelPlanRequestBuilder) addParameter("priority", priority);
    }
    
    /**
     * 设置偏好的交通方式
     * 
     * @param transportMode 交通方式
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder preferredTransportMode(String transportMode) {
        return (TravelPlanRequestBuilder) addParameter("preferredTransportMode", transportMode);
    }
    
    /**
     * 设置是否需要返程
     * 
     * @param needReturn 是否需要返程
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder needReturn(Boolean needReturn) {
        return (TravelPlanRequestBuilder) addParameter("needReturn", needReturn);
    }
    
    /**
     * 设置返程时间
     * 
     * @param returnTime 返程时间
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder returnTime(LocalDateTime returnTime) {
        return (TravelPlanRequestBuilder) addParameter("returnTime", returnTime);
    }
    
    /**
     * 配置默认值和验证规则
     * 
     * @return 当前建造者实例
     */
    public TravelPlanRequestBuilder withDefaults() {
        // 设置默认值
        setDefault("passengerCount", 1);
        setDefault("priority", "BALANCED");
        setDefault("preferredTransportMode", "ANY");
        setDefault("needReturn", false);
        
        // 如果没有指定出发时间，默认为明天同一时间
        if (!hasParameter("departureTime") && !hasParameter("departureTimeStr")) {
            setDefault("departureTime", LocalDateTime.now().plusDays(1));
        }
        
        // 添加验证规则
        required("userId")
                .addValidation("userId", 
                        value -> value instanceof Long && ((Long) value) > 0,
                        "用户ID必须是正整数");
        
        required("origin")
                .addValidation("origin",
                        value -> value.toString().trim().length() >= 2,
                        "出发地至少需要2个字符");
        
        required("destination")
                .addValidation("destination",
                        value -> value.toString().trim().length() >= 2,
                        "目的地至少需要2个字符");
        
        addValidation("passengerCount",
                value -> value instanceof Integer && ((Integer) value) > 0 && ((Integer) value) <= 20,
                "乘客数量必须在1-20之间");
        
        addValidation("budgetLimit",
                value -> value == null || (value instanceof Double && ((Double) value) > 0),
                "预算限制必须大于0");
        
        addValidation("priority",
                value -> VALID_PRIORITIES.contains(value.toString().toUpperCase()),
                "优先级必须是: " + String.join(", ", VALID_PRIORITIES));
        
        addValidation("preferredTransportMode",
                value -> VALID_TRANSPORT_MODES.contains(value.toString().toUpperCase()),
                "交通方式必须是: " + String.join(", ", VALID_TRANSPORT_MODES));
        
        // 添加时间字符串转换器
        addConverter("departureTimeStr", this::parseDateTime);
        addConverter("priority", value -> value.toString().toUpperCase());
        addConverter("preferredTransportMode", value -> value.toString().toUpperCase());
        
        return this;
    }
    
    @Override
    protected void performCustomValidation() throws ParameterValidationException {
        // 验证出发地和目的地不能相同
        String origin = getParameter("origin", String.class);
        String destination = getParameter("destination", String.class);
        
        if (origin != null && destination != null && 
            origin.trim().equalsIgnoreCase(destination.trim())) {
            throw new ParameterValidationException("出发地和目的地不能相同");
        }
        
        // 验证出发时间不能是过去时间
        LocalDateTime departureTime = getParameter("departureTime", LocalDateTime.class);
        if (departureTime != null && departureTime.isBefore(LocalDateTime.now())) {
            throw new ParameterValidationException("出发时间不能是过去时间");
        }
        
        // 如果需要返程，验证返程时间
        Boolean needReturn = getParameter("needReturn", Boolean.class, false);
        if (needReturn) {
            LocalDateTime returnTime = getParameter("returnTime", LocalDateTime.class);
            if (returnTime == null) {
                throw new ParameterValidationException("需要返程时必须指定返程时间");
            }
            
            if (departureTime != null && returnTime.isBefore(departureTime)) {
                throw new ParameterValidationException("返程时间不能早于出发时间");
            }
        }
    }
    
    @Override
    protected TravelPlanRequest doBuild() throws ParameterValidationException {
        TravelPlanRequest.TravelPlanRequestBuilder builder = TravelPlanRequest.builder()
                .userId(getParameter("userId", Long.class))
                .origin(getParameter("origin", String.class))
                .destination(getParameter("destination", String.class))
                .departureTime(getParameter("departureTime", LocalDateTime.class))
                .passengerCount(getParameter("passengerCount", Integer.class))
                .priority(getParameter("priority", String.class));
        
        // 可选参数
        Double budgetLimit = getParameter("budgetLimit", Double.class);
        if (budgetLimit != null) {
            builder.budgetLimit(budgetLimit);
        }
        
        String transportMode = getParameter("preferredTransportMode", String.class);
        if (transportMode != null && !"ANY".equals(transportMode)) {
            // 这里可以设置具体的交通方式偏好
            // 由于TravelPlanRequest可能没有这个字段，我们可以通过其他方式传递
        }
        
        Boolean needReturn = getParameter("needReturn", Boolean.class);
        if (needReturn != null && needReturn) {
            LocalDateTime returnTime = getParameter("returnTime", LocalDateTime.class);
            // 这里可以设置返程相关信息
        }
        
        return builder.build();
    }
    
    /**
     * 解析日期时间字符串
     * 
     * @param value 日期时间字符串
     * @return LocalDateTime对象
     */
    private LocalDateTime parseDateTime(Object value) {
        if (value == null) {
            return null;
        }
        
        String dateTimeStr = value.toString().trim();
        if (dateTimeStr.isEmpty()) {
            return null;
        }
        
        // 尝试多种日期格式
        String[] patterns = {
                "yyyy-MM-dd HH:mm:ss",
                "yyyy-MM-dd HH:mm",
                "yyyy-MM-dd",
                "MM-dd HH:mm",
                "MM-dd"
        };
        
        for (String pattern : patterns) {
            try {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
                
                if (pattern.equals("MM-dd HH:mm") || pattern.equals("MM-dd")) {
                    // 对于没有年份的格式，默认使用当前年份
                    String fullDateStr = LocalDateTime.now().getYear() + "-" + dateTimeStr;
                    if (pattern.equals("MM-dd")) {
                        fullDateStr += " 09:00"; // 默认上午9点
                    }
                    return LocalDateTime.parse(fullDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                } else if (pattern.equals("yyyy-MM-dd")) {
                    // 对于只有日期的格式，默认上午9点
                    return LocalDateTime.parse(dateTimeStr + " 09:00", 
                            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                } else {
                    return LocalDateTime.parse(dateTimeStr, formatter);
                }
            } catch (DateTimeParseException e) {
                // 继续尝试下一个格式
            }
        }
        
        throw new RuntimeException("无法解析日期时间格式: " + dateTimeStr + 
                "。支持的格式: yyyy-MM-dd HH:mm:ss, yyyy-MM-dd HH:mm, yyyy-MM-dd, MM-dd HH:mm, MM-dd");
    }
}